/**
* @program: src
*
* @description:
*
* @author: Mr.chen
*
* @create: 2022-04-11 16:41
**/
package server

import (
	"do_demo/srv/app/logic/rpc/internal/config"
	"do_demo/srv/app/logic/rpc/internal/pkg/helper"
	"do_demo/srv/app/logic/rpc/internal/svc"
	"do_demo/srv/common/etcdv3"
	"do_demo/srv/common/grpc/auth"
	"do_demo/srv/common/interceptor/serverinterceptors"

	pb "do_demo/srv/proto/logic"

	"do_demo/srv/common/interceptor/grpcinterceptor"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	"google.golang.org/grpc"
	"google.golang.org/grpc/keepalive"
	"log"
	"net"
	"time"
	// use gzip decoder
	_ "google.golang.org/grpc/encoding/gzip"
	"google.golang.org/grpc/reflection"
)

// New logic grpc server
func NewServer(ctx *svc.ServiceContext,l *ILogicServer) *grpc.Server {
	c := ctx.Config
	keepParams := grpc.KeepaliveParams(keepalive.ServerParameters{
		MaxConnectionIdle:     time.Duration(c.RPCServer.IdleTimeout),
		MaxConnectionAgeGrace: time.Duration(c.RPCServer.ForceCloseWait),
		Time:                  time.Duration(c.RPCServer.KeepAliveInterval),
		Timeout:               time.Duration(c.RPCServer.KeepAliveTimeout),
		MaxConnectionAge:      time.Duration(c.RPCServer.MaxLifeTime),
	})
	authenticator, _ := auth.NewAuthenticator("test","testOK")
	interceptor := grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
		grpcinterceptor.LoggerInterceptor,grpcinterceptor.RecoveryInterceptor,
		serverinterceptors.UnaryTracingInterceptor,
		serverinterceptors.UnaryPrometheusInterceptor,
		serverinterceptors.UnaryTimeoutInterceptor(5*time.Second), // 服务端处理超个5秒，直接返回超时
		serverinterceptors.UnaryAuthorizeInterceptor(authenticator),
	))
	//iStream := grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
	//	grpcinterceptor.LoggerInterceptor,grpcinterceptor.RecoveryInterceptor,
	//)),
	opt := []grpc.ServerOption{grpc.Creds(helper.GetServerCredentials()),keepParams,interceptor}
	srv := grpc.NewServer(opt...)
	pb.RegisterLogicServer(srv, l)
	lis, err := net.Listen(ctx.Config.RPCServer.Network, ctx.Config.RPCServer.Addr)
	if err != nil {
		panic(err)
	}
	Endpoints := c.Etcd.Endpoints
	ser, err := etcdv3.NewServiceRegister(Endpoints, "testsrv.apiRpc.logic", ctx.Config.RPCServer.Addr, 10)
	if err != nil {
		log.Fatalf("register service err: %v", err)
	}
	//监听续租相应chan
	go ser.ListenLeaseRespChan()
	reflection.Register(srv) // 这个是为了增加grpcui工具的使用
	go func() {
		if err := srv.Serve(lis); err != nil {
			panic(err)
		}
	}()
	s := config.Service(ctx.Config)
	if err := s.SetUp(); err != nil {
		panic(err)
	}
	return srv
}


